import pygame
from random import randint
from modules import librosa
from m2.pynput import keyboard
import time,sys,os,random,warnings,threading
import numpy as np
warnings.filterwarnings("ignore")

# 初始化游戏
pygame.init()

# 设置屏幕尺寸和标题
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("KillWG")

# 加载图片
background = pygame.image.load(r"source/bg.png")
wg_image = pygame.transform.scale(pygame.image.load(r"source/wog2.png"),(200,200))
sound_image=pygame.transform.scale(pygame.image.load(r"source/Sound.png"),(100,100))
# 加载声音
bgms=[]
wgBoom = pygame.mixer.Sound(r"source/boom.wav")
wgBoom.set_volume(0.08)
folder='source'
for filename in os.listdir(folder):
    file_path=os.path.join(folder,filename)
    try:
        pygame.mixer.music.load(file_path)
        bgms.append(file_path)
    except pygame.error:
        pass




# 窝瓜类
class Wogua(pygame.sprite.Sprite):
    def __init__(self,x,v):
        self.x = x*200
        self.y = -200
        self.v=v
    def draw(self):
        screen.blit(wg_image,(self.x,self.y))
        self.y+=self.v

def choice():
    global bgms,recordFont,bgm,difficulty,lines,details,sound_bool
    pygame.mixer.music.load(r'source\nihongjiepai.mp3')
    pygame.mixer.music.play()
    bgm=False
    down=0
    height=len(bgms)
    d=0
    details='details.txt'
    with open(details,'r') as file:
        lines=file.readlines()
    for i in bgms:
        if i+'\n' not in lines:
            lines.insert(0,'None\n')
            lines.insert(0,'p15\n')
            lines.insert(0,'None\n')
            lines.insert(0,'p30\n')
            lines.insert(0,'None\n')
            lines.insert(0,'p70\n')
            lines.insert(0,'None\n')
            lines.insert(0,'all_average:\n')
            lines.insert(0,'0\n')
            lines.insert(0,'score:\n')
            lines.insert(0,'E\n')
            lines.insert(0,'difficulty:\n')
            lines.insert(0,i+'\n')
            with open(details,'w')as file:
                file.writelines(lines)
    sound_bool=False
    while not bgm:
        screen.blit(background, (0, 0))
        for i in bgms:
            text=recordFont.render(i+'   score:'+lines[lines.index(i+'\n')+4].rstrip(),True,(255,255,255))
            text_1=recordFont.render(lines[lines.index(i+'\n')+2].rstrip(),True,(0,0,255))
            
            screen.blit(text,(60,bgms.index(i)*55+55+d))
            screen.blit(text_1,(0,bgms.index(i)*55+55+d))
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type==pygame.MOUSEBUTTONDOWN:
                button=event.button
                mx,my=event.pos
                for i in bgms:
                    if 110+55*bgms.index(i)>my>55*bgms.index(i)+55 and button==1:
                        print(i)
                        bgm=i
                if button==4 and d<height*55:
                        d+=10
                elif button==5 and d>0:
                        d-=10
            pygame.display.flip()
            time.sleep(0.03)
    difficulty='E'
    pygame.event.clear()
    while difficulty=='E':
        screen.blit(background, (0, 0))
        screen.blit(sound_image,(500,200))
        text01=recordFont.render('Easy',True,(0,0,0))
        text02=recordFont.render('Common',True,(0,0,0))
        text03=recordFont.render('Hard',True,(0,0,0))
        text04=recordFont.render('Crazy',True,(0,0,0))
        if sound_bool==True:
            text05=recordFont.render('sound:open',True,(0,0,0))
        else:
            text05=recordFont.render('sound:close',True,(0,0,0))
        screen.blit(text01,(200,5+100))
        screen.blit(text02,(200,60+100))
        screen.blit(text03,(200,115+100))
        screen.blit(text04,(200,170+100))
        screen.blit(text05,(500,300))
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type==pygame.MOUSEBUTTONDOWN:
                mx,my=event.pos
                if mx<400:
                    if my<55+100:
                        difficulty='D'
                    if 60+100<my<110+100:
                        difficulty='C'
                    if 115+100<my<165+100:
                        difficulty='B'
                    if 170+100<my<225+100:
                        difficulty='A'
                if 500<mx<600 and 200<my<300:
                    print(sound_bool)
                    if sound_bool==True:
                        sound_bool=False
                    else:
                        sound_bool=True
                    print(sound_bool)
        pygame.display.flip()
        time.sleep(0.03)

# 定义回调函数来处理键盘事件
def on_press(key):
    global k
    if 'a{}'.format(key)!=k or k[0]=='b':
        print('a{}'.format(key),'a'+str(key))
    k='a{}'.format(key)
    if True:
        return False
def on_release(key):
    global k
    k='b{}'.format(key)
    if True:
        return False
def judge(x):
    global k
    with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
        listener.start()
        listener.join()
    print(k)
    if k==1:
        pass
judge_thread=threading.Thread(target=judge)
# 主循环
def main():
    global running,score,blood,all_average,lines,difficulty,bgm,details,p70,p30,p15,wait,sound_bool
    startTime = time.time()
    timer=time.time()
    if difficulty=='D':
        v=25
        gap=0.35
        p=p70
        two=False
        three=False
    if difficulty=='C':
        v=33
        gap=0.3
        p=all_average
        two=False
        three=False
    if difficulty=='B':
        v=40
        gap=0.25
        p=p30
        two=True
        three=False
    if difficulty=='A':
        v=45
        gap=0.15
        p=p15
        two=True
        three=True
    put=0
    wgs.append(Wogua(0,v))
    wgs.append(Wogua(1,v))
    wgs.append(Wogua(2,v))
    wgs.append(Wogua(3,v))
    audio_data, _ = librosa.core.load(bgm, sr=None, duration=0.0002,offset=0.001)
    k='k'
    pygame.mixer.music.play()

    while running:
        # 绘制背景
        screen.blit(background, (0, 0))
        if pygame.mixer.music.get_busy()==False:
            pygame.mixer.music.stop()
            if lines[lines.index(bgm+'\n')+2]>=difficulty:
                lines[lines.index(bgm+'\n')+2]=difficulty+'\n'
                if score>int(float((lines[lines.index(bgm+'\n')+4].rstrip()))):
                    lines[lines.index(bgm+'\n')+4]=str(score)+'\n'
                with open(details,'w')as file:
                    file.writelines(lines)
                    
                    
            running=False
            break
        current_time = pygame.mixer.music.get_pos()/1000
        audio_data, _ = librosa.core.load(bgm, sr=None, duration=0.0002, offset=current_time+(50-v)/50+0.6)
        try:
            amplitude = librosa.core.amplitude_to_db(audio_data)
            average=np.mean(amplitude)
            if average>p:
                put=1
        except:
            pass
        
        if blood<=0:
            running=False
            break
        pygame.draw.line(screen,(255,255,255),(0,550),(800,550),5)
        if blood>4:
            pygame.draw.line(screen,(0,255,0),(600,50),(600+20*blood,50),10)
        if blood<=4:
            pygame.draw.line(screen,(255,0,0),(600,50),(600+20*blood,50),10)
        if time.time()-timer>gap and put==1:
            x1=random.randint(0,3)
            wgs.append(Wogua(x1,v))
            if two==True:
                x2=random.randint(0,3)
                if x2!=x1 and random.randint(0,4)==1:
                    wgs.append(Wogua(x2,v))
            if three==True:
                x3=random.randint(0,3)
                if x3!=x1 and x3!=x2 and random.randint(0,3)==1:
                    wgs.append(Wogua(x3,v))
            timer=time.time()
            put=0
        for i in wgs:
            i.draw()
            if i.y>600:
                wgs.remove(i)
                score-=10
                blood-=1
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if True:
                    only=False
                    for i in wgs:
                        if i.y>350 and judge(i):
                            score+=10
                            only=True
                            if blood<10:
                                blood+=1
                            wgs.remove(i)
                            if sound_bool==True:
                                wgBoom.play()
                            break
                    if only==False:
                        score-=30
                        blood-=1
        pygame.draw.line(screen,(255,255,255),(0,0),(800*current_time/length,0),4)

        # 绘制分数
        score_text = scoreFont.render(f"Score: {score}", True, (250, 255, 255))
        screen.blit(score_text, (10, 10))

        # 刷新屏幕
        pygame.display.flip()
        time.sleep(0.03)
        
# 重新开始
def replay():
    global running
    while True:
        QG=input('replay(Y/N)?')
        if QG=='N':
            break
        if QG=='Y':
            running=True
            break
# 定义各种文字
scoreFont = pygame.font.Font(None ,50)
remainTimeFont = pygame.font.Font(None ,50)
recordFont = pygame.font.Font(None ,50) 

# 游戏主循环
running = True

while running==True:
    choice()
    pygame.mixer.stop()
    music=pygame.mixer.music.load(bgm)
    length=pygame.mixer.Sound(bgm).get_length()
    print(length,'s')
    averages=[]
    text2=recordFont.render('loading……',True,(0,0,0))
    screen.blit(text2,(250,5))
    pygame.display.flip()
    if lines[lines.index(bgm+'\n')+6]=='None\n':
        for i in np.arange(0,length,0.3):
            audio_data, _ = librosa.core.load(bgm, sr=None, duration=0.0002, offset=i)
            amplitude = librosa.core.amplitude_to_db(audio_data)
            averages.append(np.mean(amplitude))
            for event in pygame.event.get():
                pass
            all_average=np.mean(averages)#极差？？
            p30=np.percentile(averages,30)
            p70=np.percentile(averages,70)
            p15=np.percentile(averages,15)
            lines[lines.index(bgm+'\n')+6]=str(all_average)+'\n'
            lines[lines.index(bgm+'\n')+8]=str(p70)+'\n'
            lines[lines.index(bgm+'\n')+10]=str(p30)+'\n'
            lines[lines.index(bgm+'\n')+12]=str(p15)+'\n'
            wait=True
    else:
        all_average=int(float(lines[lines.index(bgm+'\n')+6].rstrip()))
        p70=int(float(lines[lines.index(bgm+'\n')+8].rstrip()))
        p30=int(float(lines[lines.index(bgm+'\n')+10].rstrip()))
        p15=int(float(lines[lines.index(bgm+'\n')+12].rstrip()))
        wait=False
    print(all_average,difficulty)
    with open(details,'w')as file:
        file.writelines(lines)    
    wgs=[]
    score = 0
    blood = 10
    main()
    pygame.mixer.music.stop()

    # 结束页面
    screen.blit(background, (0, 0))
    pygame.display.flip()

    # 显示分数及历史最高
    if score > int(float(lines[lines.index(bgm+'\n')+4].rstrip())):
        score_text = scoreFont.render(f"Final Score: {score} NEW RECORD! ]", True, (255, 255, 255))
    else:
        score_text = scoreFont.render(f"Final Score: {score}", True, (255, 255, 255))
        record_text = recordFont.render("Best: {}  ".format(lines[lines.index(bgm+'\n')+2].rstrip())+'{}'.format(lines[lines.index(bgm+'\n')+4].rstrip()), True, (255 ,255, 255))
        screen.blit(record_text, (250 ,300))
    screen.blit(score_text, (250, 250))
    
    
    pygame.display.flip()
    
    
    replay()
 
while running == False:
    pygame.quit()
    sys.exit()
    break
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
        else:
            pass
